package com.purchase.ml.service.report.impl;

import com.baomidou.mybatisplus.core.assist.ISqlRunner;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.purchase.ml.bean.base.PageDto;
import com.purchase.ml.bean.page.Page;
import com.purchase.ml.bean.req.report.ReportAdminReq;
import com.purchase.ml.bean.req.report.ReportDealerReq;
import com.purchase.ml.bean.res.report.ReportAdminRes;
import com.purchase.ml.bean.res.report.ReportMasterDealerRes;
import com.purchase.ml.bean.res.report.vo.*;
import com.purchase.ml.bean.vo.dealer.DealerVo;
import com.purchase.ml.bean.vo.order.OrderCurCollectVO;
import com.purchase.ml.consts.CommonConsts;
import com.purchase.ml.consts.Constants;
import com.purchase.ml.entity.acc.SysUser;
import com.purchase.ml.entity.dealer.SysDealer;
import com.purchase.ml.entity.order.SysDealerCollect;
import com.purchase.ml.mapper.dealer.SysDealerMapper;
import com.purchase.ml.mapper.order.SysDealerCollectMapper;
import com.purchase.ml.mapper.order.SysOrderMapper;
import com.purchase.ml.security.JwtUtil;
import com.purchase.ml.service.dealer.SysDealerService;
import com.purchase.ml.service.report.ReportService;
import com.purchase.ml.utils.DataConversionUtils;
import com.purchase.ml.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by kyyang on 2021/3/4 23:12
 */
@Slf4j
@Service
@Component
public class ReportServiceImplBack {

    @Autowired
    private SysDealerService sysDealerService;

    @Autowired
    private SysDealerCollectMapper sysDealerCollectMapper;

    @Autowired
    private SysOrderMapper sysOrderMapper;

    @Autowired
    private SysDealerMapper sysDealerMapper;

   // @Override
    public ReportAdminRes queryAdminReport(ReportAdminReq req) {
        ReportAdminRes reportAdminRes = new ReportAdminRes();

        QueryWrapper<SysDealer> wrapper1 = new QueryWrapper<>();
        wrapper1.eq("state",1);
        wrapper1.eq("dealer_type",CommonConsts.ROLETYPE_MASTER);
        List<SysDealer> sysDealers = sysDealerMapper.selectList(wrapper1);

        List<Long> dealers = sysDealers.stream().map(e -> e.getDealerId()).collect(Collectors.toList());
        QueryWrapper<SysDealerCollect> wrapper = new QueryWrapper<>();
        Calendar instance = Calendar.getInstance();
        wrapper.apply("data_date>=str_to_date({0},'%Y-%m-%d') and data_date<=str_to_date({1},'%Y-%m-%d')",req.getStartTime(),req.getEndTime());
        if(dealers==null||dealers.size()<1){
            return reportAdminRes;
        }
        List<SysDealerCollect> sysDealerCollects = sysDealerCollectMapper.selectList(wrapper);
        
        if(sysDealerCollects.size() == 0 || sysDealerCollects == null ){
            sysDealerCollects = new ArrayList<>();
        }
        if(sysDealerCollects != null && sysDealerCollects.size()>0){
            Map<String, Double> map = sysDealerCollects.stream().collect(Collectors.groupingBy(e -> DateUtils.dayFormat.get().format(e.getDataDate()) , Collectors.summingDouble(e -> e.getTotalProfitCur().doubleValue())));
            reportAdminRes.setProfitDetail(DataConversionUtils.getCurDateMonthDataInit(req.getStartTime(),req.getEndTime(),map));
            //汇总 总订单数
            long total_pos = sysDealerCollects.stream().collect(Collectors.summingLong(SysDealerCollect::getPurchaseOrdNumAgg)).longValue();
            //汇总总销售额
            Double total_sales = sysDealerCollects.stream().collect(Collectors.summingDouble(o->o.getTotalSalesAgg().doubleValue())).doubleValue();
            //汇总总利润
            Double total_profit = sysDealerCollects.stream().collect(Collectors.summingDouble(o->o.getTotalProfitAgg().doubleValue())).doubleValue();
           //汇总主每个经销商
            Map<Long, List<SysDealerCollect>> dealerMap = sysDealerCollects.stream().filter(e -> e.getDealerType() == CommonConsts.ROLETYPE_MASTER ).collect(Collectors.groupingBy(o -> o.getDealerId()));
            List<ReportDealerSalesDetailVo> reportDealerSalesDetailVos = new ArrayList<>();

            Map<Integer, List<SysDealerCollect>> collect = sysDealerCollects.stream().map(s -> sysDealers.stream().filter(sd -> s.getDealerId().equals(sd.getDealerId())).findFirst()
                    .map(i -> {
                        s.setRegion(i.getRegion());
                        return s;
                    }).orElse(null)).filter(a -> a != null).collect(Collectors.groupingBy(SysDealerCollect::getRegion));

            List<ReportRegoinCollectVo> reportRegoinCollectVos = collect.entrySet().stream().map(e -> {
                ReportRegoinCollectVo v1 = new ReportRegoinCollectVo();
                v1.setRegionName(e.getKey()+"");
                List<SysDealerCollect> value = e.getValue();
                if(value!=null&&value.size()>0){
                    double sum = value.stream().mapToDouble(f -> f.getTotalSalesCur().doubleValue()).sum();
                    v1.setTotalSales(BigDecimal.valueOf(sum));
                    Map<String, Double> collect1 = value.stream().collect(Collectors.groupingBy(f ->DateUtils.dayFormat.get().format(f.getDataDate()), Collectors.summingDouble(z -> z.getTotalSalesCur().doubleValue())));
                    v1.setDetails(DataConversionUtils.getCurDateMonthDataInit(req.getStartTime(),req.getEndTime(),collect1));
                }
                return v1;
            }).collect(Collectors.toList());
            if(dealerMap!=null&&dealerMap.size()>0){
                for(Map.Entry<Long,List<SysDealerCollect>> entry :dealerMap.entrySet()){
                    ReportDealerSalesDetailVo reportDealerSalesDetailVo = new ReportDealerSalesDetailVo();
                    reportDealerSalesDetailVo.setDealerId(entry.getKey());
                    double sum = entry.getValue().stream().mapToDouble(e -> e.getTotalSalesCur().doubleValue()).sum();

                    Map<String, Double> collect1 = entry.getValue().stream().collect(Collectors.groupingBy(q -> DateUtils.dayFormat.get().format(q.getDataDate()), Collectors.summingDouble(w -> w.getTotalSalesCur().doubleValue())));
                    SysDealer sysDealer = sysDealerMapper.selectByDealerId(entry.getKey());
                    reportDealerSalesDetailVo.setDealerName(sysDealer==null?"":sysDealer.getDealerName());
                    reportDealerSalesDetailVo.setDetails(DataConversionUtils.getCurDateMonthDataInit(req.getStartTime(),req.getEndTime(),collect1));
                    reportDealerSalesDetailVo.setTotalSales(BigDecimal.valueOf(sum));
                    reportDealerSalesDetailVos.add(reportDealerSalesDetailVo);
                }
            }
            //按照金额降序并取前10
            if(reportDealerSalesDetailVos!=null&&reportDealerSalesDetailVos.size()>0){
                reportDealerSalesDetailVos = reportDealerSalesDetailVos.stream().sorted(Comparator.comparing(ReportDealerSalesDetailVo::getTotalSales).reversed()).collect(Collectors.toList());
                if(reportDealerSalesDetailVos.size()>10){
                    reportDealerSalesDetailVos = reportDealerSalesDetailVos.subList(0,10);
                }
            }
            reportAdminRes.setRegoinCollect(reportRegoinCollectVos);
            reportAdminRes.setMasterDealerSales(reportDealerSalesDetailVos);
            reportAdminRes.setTotalPOs(total_pos);
            reportAdminRes.setTotalProfit(BigDecimal.valueOf(total_profit));
            reportAdminRes.setTotalSales(BigDecimal.valueOf(total_sales));
        }
        return reportAdminRes;
    }

   // @Override
    public Page<ReportDealerSalesVo> queryMasterDealerSalesPageReport(ReportDealerReq reportDealerReq) {
        Page<ReportDealerSalesVo> result = new Page<ReportDealerSalesVo>(reportDealerReq.getPageIndex(),reportDealerReq.getPageNum());
        QueryWrapper<SysDealerCollect> wrapper = new QueryWrapper<>();
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<SysDealerCollect> page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(reportDealerReq.getPageIndex(), reportDealerReq.getPageNum());

        wrapper.apply("data_date>=str_to_date({0},'%Y-%m-%d') and data_date<=str_to_date({1},'%Y-%m-%d')",reportDealerReq.getStartTime(),reportDealerReq.getEndTime());

        SysUser currentUser = JwtUtil.getCurrentUser();
        if(currentUser.getRoleType()==CommonConsts.ROLETYPE_MASTER){
            wrapper.eq("dealer_type",CommonConsts.ROLETYPE_DEALER);
        }else{
            wrapper.eq("dealer_type",CommonConsts.ROLETYPE_MASTER);
        }
        if(reportDealerReq.getDealerId()!=null){
            wrapper.eq("parent_id",reportDealerReq.getDealerId());
        }

        com.baomidou.mybatisplus.extension.plugins.pagination.Page<SysDealerCollect> sysDealerCollectPage = sysDealerCollectMapper.selectPage(page, wrapper);
        Long total = sysDealerCollectPage.getTotal();
        result.setTotal(total.intValue());
        List<SysDealerCollect> records = sysDealerCollectPage.getRecords();
        List<ReportDealerSalesVo> collect = new ArrayList<>();
        if(records!=null&&records.size()>0){
            Map<Long, Double> collect1 = records.stream().collect(Collectors.groupingBy(g -> g.getDealerId(), Collectors.summingDouble(g -> g.getTotalSalesCur().doubleValue())));
            collect= collect1.entrySet().stream().map(o->{
                ReportDealerSalesVo vo = new ReportDealerSalesVo();
                SysDealer sysDealer = sysDealerMapper.selectByDealerId(o.getKey());
                vo.setDealerName(sysDealer.getDealerName());
                vo.setTotalSales(BigDecimal.valueOf(o.getValue()));
                vo.setDealerId(sysDealer.getDealerId()+"");
                return vo;
            }).collect(Collectors.toList());
        }
        result.setRecords(collect);
        return result;
    }



    //@Override
    public ReportMasterDealerRes queryMasterDealerReport(ReportAdminReq req) {
        ReportMasterDealerRes reportMasterDealerRes = new ReportMasterDealerRes();
        QueryWrapper<SysDealer> wrapper0 = new QueryWrapper<>();
        wrapper0.ne("state", Constants.DEALER_STATE_DELETE);
        wrapper0.eq("dealer_type",CommonConsts.ROLETYPE_DEALER);
        //只有管理员与大代理才能通过经销商筛选统计报告
        wrapper0.eq("superior",req.getDealerId());
        List<DealerVo> currentUserDear = sysDealerMapper.selectList(wrapper0).stream().map(e -> new DealerVo(e.getDealerId(), e.getDealerType(),e.getState(),e.getIsAuth())).collect(Collectors.toList());
        List<Long> dealers = currentUserDear.stream().map(e -> e.getDealerId()).collect(Collectors.toList());
        QueryWrapper<SysDealerCollect> wrapper = new QueryWrapper<>();
        Calendar instance = Calendar.getInstance();
        if(dealers==null||dealers.size()<1){
            return reportMasterDealerRes;
        }
        wrapper.in("dealer_id",dealers);
        wrapper.apply("data_date>=str_to_date({0},'%Y-%m-%d') and data_date<=str_to_date({1},'%Y-%m-%d')",req.getStartTime(),req.getEndTime());
        List<SysDealerCollect> sysDealerCollects = sysDealerCollectMapper.selectList(wrapper);
        if(sysDealerCollects==null){
            sysDealerCollects = new ArrayList<>();
        }
        if(sysDealerCollects!=null && sysDealerCollects.size()>0){
            //Map<String, Double> map = sysDealerCollects.stream().collect(Collectors.groupingBy(e -> e.getDay() + "", Collectors.summingDouble(e -> e.getTotalProfitCur().doubleValue())));
            //汇总 总订单数
            long total_pos = sysDealerCollects.stream().collect(Collectors.summingLong(SysDealerCollect::getPurchaseOrdNumAgg)).longValue();
            //汇总总销售额
            Double total_sales = sysDealerCollects.stream().collect(Collectors.summingDouble(o->o.getTotalSalesAgg().doubleValue())).doubleValue();
            //汇总总利润
            Double total_profit = sysDealerCollects.stream().collect(Collectors.summingDouble(o->o.getTotalProfitAgg().doubleValue())).doubleValue();
            //汇总主每个经销商
            Map<Long, List<SysDealerCollect>> dealerMap = sysDealerCollects.stream().filter(e -> e.getDealerType() == CommonConsts.ROLETYPE_AGENCY).collect(Collectors.groupingBy(o -> o.getDealerId()));
            List<ReportDealerSalesDetailVo> reportDealerSalesDetailVos = new ArrayList<>();

            if(dealerMap!=null&&dealerMap.size()>0){
                for(Map.Entry<Long,List<SysDealerCollect>> entry :dealerMap.entrySet()){
                    ReportDealerSalesDetailVo reportDealerSalesDetailVo = new ReportDealerSalesDetailVo();
                    reportDealerSalesDetailVo.setDealerId(entry.getKey());
                    double sum = entry.getValue().stream().mapToDouble(e -> e.getTotalSalesCur().doubleValue()).sum();
                    Map<String, Double> collect1 = entry.getValue().stream().collect(Collectors.groupingBy(q -> DateUtils.dayFormat.get().format(q.getDataDate()), Collectors.summingDouble(w -> w.getTotalSalesCur().doubleValue())));
                    SysDealer sysDealer = sysDealerMapper.selectByDealerId(entry.getKey());
                    reportDealerSalesDetailVo.setDealerName(sysDealer==null?"":sysDealer.getDealerName());
                    reportDealerSalesDetailVo.setDetails(DataConversionUtils.getCurDateMonthDataInit(req.getStartTime(),req.getEndTime(),collect1));
                    reportDealerSalesDetailVo.setTotalSales(BigDecimal.valueOf(sum));
                    reportDealerSalesDetailVos.add(reportDealerSalesDetailVo);
                }
            }
            //按照金额降序并取前10
            if(reportDealerSalesDetailVos!=null&&reportDealerSalesDetailVos.size()>0){
                reportDealerSalesDetailVos = reportDealerSalesDetailVos.stream().sorted(Comparator.comparing(ReportDealerSalesDetailVo::getTotalSales).reversed()).collect(Collectors.toList());
                if(reportDealerSalesDetailVos.size()>10){
                    reportDealerSalesDetailVos = reportDealerSalesDetailVos.subList(0,10);
                }
            }

            reportMasterDealerRes.setMasterDealerSales(reportDealerSalesDetailVos);
            reportMasterDealerRes.setTotalPOs(total_pos);
            reportMasterDealerRes.setTotalProfit(BigDecimal.valueOf(total_profit));
            reportMasterDealerRes.setTotalSales(BigDecimal.valueOf(total_sales));
        }
        return reportMasterDealerRes;

    }


}
